Skip to content

Add [\!shouldfail] reproducer for transitive implicit-dep tracking bug#48

Closed
typeless wants to merge 1 commit into
feature/show-indexfrom
reproducer/transitive-implicit-dep
Closed

Add [\!shouldfail] reproducer for transitive implicit-dep tracking bug#48
typeless wants to merge 1 commit into
feature/show-indexfrom
reproducer/transitive-implicit-dep

Conversation

@typeless

@typeless typeless commented May 15, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a minimal failing reproducer for a real bug in pup's implicit-dep recording, currently tagged [\!shouldfail] so CI stays green while the bug is on file. Depends on #49 (uses pup show index for forensic diagnostic output).

The bug

When an already-tracked header is edited to #include a new header, the source's recompile produces a .d file listing the new header, but pup's index does not extend the source's implicit-dep set to include it. Subsequent edits to the newly-introduced header are then invisible to change detection — pup reports Nothing to do (up to date). while the .o is stale.

This is distinct from the scope-filter bug fixed in 315b2a2 (where an existing-recorded header was filtered out during change detection). The new bug fires unscoped and is a flaw in dep recording, not change detection.

Reproducer steps (see test/e2e/fixtures/header_dep_transitive/test.sh)

  1. main.c includes only old.h. Initial build records old.h as implicit dep. .o contains 0x1 (ANSWER=1). ✓
  2. Edit old.h to #include "newhdr.h" and use EXTRA. Rebuild. .o contains 0x64 (EXTRA=100). ✓ (compile happened, .d listed newhdr.h)
  3. Edit newhdr.h (EXTRA 100 → 7777). Rebuild expected. Observed: Nothing to do. .o stays at 0x64. ✗

Between steps 2 and 3, test.sh runs pup show index PATTERN (from #49) and asserts whether newhdr.h appears in main.c's implicit-dep set. Live result on this branch:

implicit: src/main.c
implicit: /usr/include/stdc-predef.h
implicit: include/old.h          ← recorded ✓
                                 ← newhdr.h missing ✗
sticky:   src/Tupfile

This isolates the root cause precisely: pup's post-execution .d-file processing does not extend the implicit-dep set with newly-discovered transitive headers after a rebuild. The bug is therefore in the dep-recording path (around discovered_deps/process_implicit_deps in cmd_build.cpp), not in change detection.

Why [\!shouldfail]

Catch2's [\!shouldfail] marks the test as an expected-failure: it runs, output is captured, exit status reports 1 failed as expected. Default CI stays green. Once the dep-recording bug is fixed and the test passes, removing the tag converts it into a regression guard.

Test plan

  • Reproducer runs standalone: bash test/e2e/fixtures/header_dep_transitive/test.sh exits 1 with diagnostic output showing stale .o AND the forensic from pup show index pinpointing the missing edge
  • Catch2 SCENARIO via ./build/test/unit/putup_test "[\!shouldfail]" reports 1 failed as expected
  • Full test suite is green (the SCENARIO does not break CI)
  • make format clean

Refs pup-header-detection-bug.md (working notes), depends on #49.

🤖 Generated with Claude Code

@typeless typeless mentioned this pull request May 15, 2026
4 tasks
Minimal fixture demonstrating that pup fails to record a newly-transitive header when an existing tracked header is edited to include it. After the edit, the source's recompile produces a .d file listing the new header, but pup's implicit-dep set is not extended — so subsequent edits to the new header are invisible to change detection and pup reports "Nothing to do" while the .o is stale.

Reproducer (test.sh):
  1. source.c includes only old.h. Build, record old.h as implicit dep.
  2. Edit old.h to also #include newhdr.h. Rebuild. .o picks up new value via newhdr.h.
  3. Edit newhdr.h. Rebuild expected; pup reports "Nothing to do". .o stale.

Tagged [\!shouldfail] so default CI stays green while the bug is on file. Once the underlying dep-recording bug is fixed, removing the tag converts this into a regression guard.

The bug reproduces unscoped (no scope filter) and is distinct from the change-detection scope-filter bug fixed in 315b2a2 — that one was about an existing recorded header being filtered out; this is about a header never being recorded in the first place.

Refs pup-header-detection-bug.md (working notes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@typeless typeless force-pushed the reproducer/transitive-implicit-dep branch from 5b016f9 to 1cd9d64 Compare May 15, 2026 06:15
@typeless typeless changed the base branch from main to feature/show-index May 15, 2026 06:15
@typeless typeless deleted the branch feature/show-index May 15, 2026 06:25
@typeless typeless closed this May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant